package com.pan.admin.module.visualizer.entity.vo;

import com.gitee.apanlh.util.base.BigDecimalUtils;
import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.base.Empty;
import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.base.IteratorUtils;
import com.gitee.apanlh.util.valid.ValidParam;
import com.pan.admin.common.constant.ProductApplyFlowStatusEnum;
import com.pan.admin.common.redis.DataExchangeRedisKey;
import com.pan.admin.module.visualizer.entity.po.ApiVisualizerPO;
import lombok.Data;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;

/**
 *  API数据可视化VO实体
 *  @author Pan
 */
@Data
public class ApiVisualizerVO {

    /** API名称 */
    private String apiName;
    /** APIClientId */
    private String apiClientId;
    /** ---------------撞库-------------------- */
    /** 撞库总数 */
    private Integer dataExchangeTotal;
    /** 机构/平台撞库成功总条数 */
    private Integer dataExchangeSucTotal;
    /** 机构/平台撞库失败总条数 */
    private Integer dataExchangeFailTotal;
    /** 撞库成功率 */
    private String dataExchangeRatio;

    /** ---------------进件-------------------- */
    /** 进件失败总条数 */
    private Integer applyBizFailTotal;
    /** 机构/平台进件失败总条数 */
    private Integer applyFailTotal;
    /** 用户授权/进件总数总条数 */
    private Integer userAcceptTotal;
    /** 进件成功率 */
    private String applySucRatio;
    /** ---------------回调-------------------- */
    /** 用户进入回调授权页面总条数 */
    private Integer callUserIntoTotal;

    /** ---------------收益-------------------- */
    /** 总成本 */
    private BigDecimal totalCost;
    /** 总收入 */
    private BigDecimal totalRevenue;
    /** 总收益 */
    private BigDecimal totalProfit;
    /** ROI计算 */
    private BigDecimal roi;
    /** 截止时间 */
    private String dateTime;

    /**
     *  转换VO
     *
     *  @param  list
     *  @return List
     */
    public static List<ApiVisualizerVO> convert(List<ApiVisualizerPO> list) {
        if (ValidParam.isEmpty(list)) {
            return Empty.list();
        }
        List<ApiVisualizerVO> listVO = CollUtils.newArrayList();

        //  分组客户端id
        Map<String, List<ApiVisualizerPO>> apiMap = CollUtils.groupBy(list, t -> t.getApiClientId());
        IteratorUtils.entrySet(apiMap, (key, listApi) -> {
            ApiVisualizerVO apiVisualizerVO = new ApiVisualizerVO();
            ApiVisualizerPO first = IteratorUtils.getFirst(listApi);
            apiVisualizerVO.setApiName(first.getApiName());
            apiVisualizerVO.setApiClientId(first.getApiClientId());
            //  状态分组
            Map<Integer, List<ApiVisualizerPO>> statusMap = CollUtils.groupBy(listApi, t -> t.getStatus());

            //  撞库统计
            {
                //  撞库总数
                String apiClientId = apiVisualizerVO.getApiClientId();
                if (DataExchangeRedisKey.DATA_EXCHANGE_TOTAL.exists(apiClientId)) {
                    Integer dataExchangeTotal = DataExchangeRedisKey.DATA_EXCHANGE_TOTAL.get(apiClientId, Integer.class);
                    apiVisualizerVO.setDataExchangeTotal(dataExchangeTotal);
                }

                //  撞库成功总数
                ApiVisualizerPO dataChangeSuc = getByStatus(statusMap, ProductApplyFlowStatusEnum.DATA_EXCHANGE_SUC);
                if (ValidParam.isNotNull(dataChangeSuc)) {
                    apiVisualizerVO.setDataExchangeSucTotal(dataChangeSuc.getTotal());
                }

                //  机构撞库失败总数
                ApiVisualizerPO orgDataChangeFail = getByStatus(statusMap, ProductApplyFlowStatusEnum.DATA_EXCHANGE_FAIL);
                Integer orgTotal = 0;
                if (ValidParam.isNotNull(orgDataChangeFail)) {
                    orgTotal = orgDataChangeFail.getTotal();
                }

                //  平台撞库失败总数
                ApiVisualizerPO platDataChangeFail = getByStatus(statusMap, ProductApplyFlowStatusEnum.PLAT_FORM_DATA_EXCHANGE_FAIL);
                Integer platTotal = 0;
                if (ValidParam.isNotNull(platDataChangeFail)) {
                    platTotal = platDataChangeFail.getTotal();
                }
                //  撞库失败总数
                Integer dataExchangeFailTotal = orgTotal + platTotal;
                apiVisualizerVO.setDataExchangeFailTotal(dataExchangeFailTotal);

                //  撞库成功比例
                Integer dataExchangeSucTotal = apiVisualizerVO.getDataExchangeSucTotal();
                //  分母
                BigDecimal dataExchangeSucRatio = BigDecimalUtils.toBigDecimal(dataExchangeSucTotal)
                    .divide(BigDecimalUtils.toBigDecimal(dataExchangeSucTotal + dataExchangeFailTotal), 4, RoundingMode.DOWN)
                    .multiply(BigDecimal.valueOf(100))
                .setScale(2, RoundingMode.DOWN);
                apiVisualizerVO.setDataExchangeRatio(dataExchangeSucRatio.toString() + "%");
            }

            //  进件统计
            {
                //  进件业务校验失败总数
                ApiVisualizerPO applyBizFail = getByStatus(statusMap, ProductApplyFlowStatusEnum.APPLY_BIZ_ERROR);
                if (ValidParam.isNotNull(applyBizFail)) {
                    apiVisualizerVO.setApplyBizFailTotal(applyBizFail.getTotal());
                }

                //  进件失败总数
                ApiVisualizerPO applyFail = getByStatus(statusMap, ProductApplyFlowStatusEnum.APPLY_ERROR);
                Integer applyFailTotal = 0;
                if (ValidParam.isNotNull(applyFail)) {
                    applyFailTotal = applyFail.getTotal();
                    apiVisualizerVO.setApplyFailTotal(applyFailTotal);
                }

                //  进件总数
                ApiVisualizerPO userAccept = getByStatus(statusMap, ProductApplyFlowStatusEnum.USER_ACCEPT);
                Integer applySucTotal = 0;
                if (ValidParam.isNotNull(userAccept)) {
                    //  用户授权总数/进件总数
                    applySucTotal = userAccept.getTotal();
                    apiVisualizerVO.setUserAcceptTotal(applySucTotal);
                }

                //  进件成功比例
                BigDecimal applySucRatio = BigDecimalUtils.toBigDecimal(applySucTotal)
                    .divide(BigDecimalUtils.toBigDecimal(applySucTotal + applyFailTotal), 4, RoundingMode.DOWN)
                    .multiply(BigDecimal.valueOf(100))
                .setScale(2, RoundingMode.DOWN);
                apiVisualizerVO.setApplySucRatio(applySucRatio.toString() + "%");
            }

            //  回调统计
            {
                //  用户进入回调-授权页待授权数
                ApiVisualizerPO userInto = getByStatus(statusMap, ProductApplyFlowStatusEnum.CALLBACK_USER_INTO);
                if (ValidParam.isNotNull(userInto)) {
                    apiVisualizerVO.setCallUserIntoTotal(userInto.getTotal());
                }
            }

            //  收益统计
            {
                ApiVisualizerPO userAccept = getByStatus(statusMap, ProductApplyFlowStatusEnum.USER_ACCEPT);
                if (ValidParam.isNotNull(userAccept)) {
                    Integer total = userAccept.getTotal();

                    //  总成本统计 = 总成本 * 授权总数
                    BigDecimal totalCost = userAccept.getTotalCost();
                    if (totalCost.toString().equals("0.00")) {
                        apiVisualizerVO.setTotalCost(totalCost);
                    } else {
                        totalCost = BigDecimalUtils.multiply(total, totalCost);
                        apiVisualizerVO.setTotalCost(totalCost);
                    }

                    //  总收益
                    BigDecimal totalRevenue = userAccept.getTotalRevenue();
                    apiVisualizerVO.setTotalRevenue(totalRevenue);

                    //  渠道抽成模式
                    BigDecimal apiShare = userAccept.getApiShare();
                    if (!Eq.str(apiShare.toString(), "0.00")) {
                        //  原价 * (1 / 渠道分成份额%)
                        String base = "1";
                        BigDecimal percent = BigDecimalUtils.minus(base, BigDecimalUtils.division(apiShare, 100));
                        //  收益-保留两位小数
                        BigDecimal profit = totalRevenue.multiply(percent);
                        apiVisualizerVO.setTotalProfit(profit);

                        //  收益-利润 = 成本
                        BigDecimal shareCost = BigDecimalUtils.minus(totalRevenue, profit);
                        apiVisualizerVO.setTotalCost(shareCost);
                    } else {
                        //  无抽成模式
                        //  总利润
                        apiVisualizerVO.setTotalProfit(totalRevenue.subtract(totalCost));
                    }

                    //  ROI
                    BigDecimal totalCostROI = apiVisualizerVO.getTotalCost();
                    //  非0成本计算ROI
                    if (!totalCostROI.toString().equals("0.00")) {
                        BigDecimal totalProfitROI = apiVisualizerVO.getTotalRevenue();
                        BigDecimal roi = BigDecimalUtils.minus(totalProfitROI, totalCostROI).setScale(2, RoundingMode.DOWN)
                            .divide(totalCostROI, 2, RoundingMode.DOWN)
                            .multiply(new BigDecimal("100"));
                        apiVisualizerVO.setRoi(roi);
                    }
                }
            }
            listVO.add(apiVisualizerVO);
        });
        return listVO;
    }

    /**
     *  根据状态获取对应数据
     *
     *  @param  statusMap
     *  @param  productApplyFlowStatusEnum
     *  @return ApiVisualizerPO
     */
    private static ApiVisualizerPO getByStatus(Map<Integer, List<ApiVisualizerPO>> statusMap, ProductApplyFlowStatusEnum productApplyFlowStatusEnum) {
        List<ApiVisualizerPO> list = statusMap.get(productApplyFlowStatusEnum.getType());
        if (ValidParam.isNotEmpty(list)) {
            return IteratorUtils.getFirst(list);
        }
        return null;
    }
}
